home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / emerald / emrldsys.lha / Kernel / Em / sigio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-17  |  4.6 KB  |  183 lines

  1. #ifndef xkernel
  2. #ifdef BSD
  3. /*  C O P Y R I G H T   N O T I C E :                                     */
  4. /* Copyright 1986 Eric Jul.  May not be used for any               */
  5. /* purpose without written permission from the author.              */
  6. /*
  7.  * INTERFACE:   Defined by exported procedures.
  8.  *
  9.  * FUNCTION:    Provides multiplexing of SIGIO when multiple asynchronous
  10.  *              sockets are used.
  11.  *
  12.  * EXPORTS:     SISetSockHandler, SIRemoveSockHandler
  13.  *
  14.  * TRACES:      SI
  15.  *
  16.  * SNAPSHOTS:   None
  17.  *
  18.  *
  19.  * DESIGN:      Handlers are set on a per socket basis and
  20.  *              are invoked when "select" shows that i/o is possible.
  21.  */
  22.  
  23. #include <errno.h>
  24. #include <sys/ioctl.h>
  25. #include <sys/time.h>
  26. #include <signal.h>
  27. #include "Kernel/h/system.h"
  28. #include "Kernel/h/assert.h"
  29. #include "Kernel/h/stdTypes.h"
  30. #include "Kernel/h/sigio.h"
  31. #include "Kernel/h/kmdTypes.h"
  32.  
  33. extern void SetHandler();
  34. extern int errno;
  35.  
  36. /* Forward */ void SIRemoveSockHandler();
  37.  
  38. SIHandlerPtr            table[3][32];
  39. static int              SIInitialized = 0;
  40. int                     mask[3] = { 0, 0, 0};
  41. int                     maxSock = 0;
  42. static struct timeval   timeout  = {0, 0};
  43.  
  44. #define DEFAULTSIGIODELAYTIME       50000 /* microseconds */
  45. int                     vSIDelayTime = DEFAULTSIGIODELAYTIME;
  46.  
  47. int SICheck(fSock)
  48. /* Check for broken sockets */
  49. {
  50.     int chck[3], nfound;
  51.     while (1) {
  52.     chck[0] = chck[1] = chck[2] = 1 << fSock;
  53.     nfound = select(fSock+1, &chck[0], &chck[1], &chck[2], &timeout);
  54.     if (nfound >= 0) return 1;
  55.     if (errno != EINTR) return 0;
  56.     }
  57. }
  58.  
  59. void SIFixBadF()
  60. /* Clean up Sock structure, generating upcalls for dead sockets */
  61. {
  62.     int i, j;
  63.     SIHandlerPtr    theHandler;
  64.     
  65.     for (j = 0; j <= maxSock; j++)
  66.     for (i = 0; i < 3; i++)
  67.     if (((int) table[i][j]) != 0) {
  68.     if (!SICheck(j)) {
  69.         theHandler = table[SIEXCEPT][j];
  70.         SIRemoveSockHandler(j, SIREAD);
  71.         SIRemoveSockHandler(j, SIWRITE);
  72.         SIRemoveSockHandler(j, SIEXCEPT);
  73.         if (((int)theHandler) != 0) {
  74.         QueueTask(theHandler, (char *) j);
  75.         }
  76.         break;
  77.     }
  78.     }
  79. }
  80.  
  81. void SIInterrupt()
  82. /* Signal handler for SIGIO */
  83. {
  84.     int nfound, result[3];
  85.     register int i, j;
  86.     
  87. retry:
  88.     result[0] = mask[0];
  89.     result[1] = mask[1];
  90.     result[2] = 0;
  91.     nfound = select(maxSock+1, &result[0], &result[1], &result[2], &timeout);
  92.     if (nfound == 0) return;
  93.     if (nfound < 0) {
  94.     if (errno == EINTR) goto retry;
  95.     if (errno == EBADF) {
  96.         SIFixBadF();
  97.         goto retry;
  98.     }
  99.     ErrMsg("Bad return from select\n");
  100.     perror("select");
  101.     abort();
  102.     }
  103.     for (i = 0; i < 2; i++)
  104.     for (j = 0; j <= maxSock; j++)
  105.     if (result[i] & (1<<j)) {
  106.     (*table[i][j])(i,j);
  107.     }
  108. }
  109.  
  110. void SIEnsureSIGIO()
  111. /* At times, it is necessary to ensure that a SIGIO happens.
  112.    This procedure ensures this by scheduling a SIGIO event after
  113.    in vSIDelayTime microseconds. */
  114. {
  115.     (void) MMSetMicroTimer(vSIDelayTime/1000000, vSIDelayTime % 1000000,
  116.     SIInterrupt, NULL, NULL);
  117. }
  118.  
  119. void SIInit()
  120. {
  121.     register i,j;
  122.     KMDSetTrace(SI);
  123.     KMDTrace("SI", 3, "Initializing SIGIO\n");
  124.     for (i=0; i < 3; i++)
  125.     for (j=0; j < 32; j++) table[i][j] = (SIHandlerPtr) NULL;
  126.     SetHandler(SIGIO, SIInterrupt);
  127.     SetHandler(SIGPIPE, SIFixBadF);
  128.     SIInitialized = 1;
  129. }
  130.  
  131. void SISetSockHandler(fSock, fKind, fHandler)
  132. int                 fSock;
  133. int                 fKind;
  134. SIHandlerPtr        fHandler;
  135. /* Define a handler for a socket.  There are three kinds of handlers:
  136.    read:            invoked when input is possible on the socket
  137.    write:           invoked when output is possible on the socket
  138.    death:           invoked when the socket has died and gone away
  139.             (death upcall).
  140. */
  141. {
  142.     if (!SIInitialized) SIInit();
  143.     assert(fSock >= 0 && fSock < 32);
  144.     assert(fKind >= SIREAD && fKind <= SIEXCEPT);
  145.     table[fKind][fSock] = fHandler;
  146.     mask[fKind] |= (1 << fSock);
  147.     if (fSock > maxSock) maxSock = fSock;
  148. }
  149.  
  150. void SIRemoveSockHandler(fSock, fKind)
  151. int                 fSock;
  152. int                 fKind;
  153. /* Remove a handler */
  154. {
  155.     assert(SIInitialized);
  156.     assert(fSock >= 0 && fSock < 32);
  157.     assert(fKind >= SIREAD && fKind <= SIEXCEPT);
  158.     table[fKind][fSock] = (SIHandlerPtr) NULL;
  159.     mask[fKind] &= ~ (1<<fSock);
  160.     if (fSock >= maxSock) {
  161.     register int i, j, oldMaxSock;
  162.     oldMaxSock = maxSock;
  163.     maxSock = 0;
  164.     for (i=0; i < 2; i++)
  165.     for (j=maxSock; j <= oldMaxSock; j ++)
  166.     if (table[i][j] != (SIHandlerPtr) NULL) maxSock = j;
  167.     }
  168. }
  169.  
  170.  
  171. /****************************************************************/
  172. /*          End of SIGIO handling                               */
  173. /****************************************************************/
  174. #endif
  175. #else
  176. void SISetSockHandler()
  177. {}
  178. void SIRemoveSockHandler()
  179. {}
  180. void SIEnsureSIGIO()
  181. {}
  182. #endif
  183.